﻿using System;
using System.Collections.Generic;
using System.Text;
using com.dz.dataaccess;
using com.dz.entity;
using com.dz.common;
using System.Data;
using System.Text.RegularExpressions;
using System.Web;
namespace com.dz.components
{
    public class CatchBaiDuVipManager
    {
        /// <summary>
        /// 百度首页编码
        /// </summary>
        Encoding m_encoding = Encoding.GetEncoding("gb2312");

        /// <summary>
        /// 文件对象
        /// </summary>
        FileManager m_file_mgr = new FileManager();

        DataSet m_ds = null;

        Dictionary<long, long> m_dic = new Dictionary<long, long>();

        static object m_obj = new object();

        /// <summary>
        /// 章节操作对象
        /// </summary>
        BookChapterManager m_chapter_manager = new BookChapterManager();

        public void StartCatchVipChpater()
        {
            m_ds = m_chapter_manager.GetCatchVipChapter();

          

            long t_book_id = 0;
            long t_chapter_id = 0;
            if (m_ds != null && m_ds.Tables.Count > 0 && m_ds.Tables[0].Rows.Count > 0)
            {
                for (int t_index = 0; t_index <= m_ds.Tables[0].Rows.Count;t_index++ )
                {
                  
                    if (t_index == m_ds.Tables[0].Rows.Count )
                    {
                        System.Threading.Thread.Sleep(10  * 1000);
                        t_index = 0;
                        m_ds = m_chapter_manager.GetCatchVipChapter();
                    }

                    if (!long.TryParse(m_ds.Tables[0].Rows[t_index]["bookid"].ToString(), out t_book_id))
                        t_book_id = 0;
                    if (!long.TryParse(m_ds.Tables[0].Rows[t_index]["chapterid"].ToString(), out t_chapter_id))
                        t_chapter_id = 0;

                    StartCatch(t_book_id, t_chapter_id, m_ds.Tables[0].Rows[t_index]["bookname"].ToString(), m_ds.Tables[0].Rows[t_index]["chaptername"].ToString());

                    continue;

                    //刚刚抓过的书就不要再抓了
                    if (m_dic.ContainsKey(t_chapter_id))
                        continue;
                    lock (m_obj)
                    {
                        if (!m_dic.ContainsKey(t_chapter_id))
                            m_dic.Add(t_chapter_id, t_chapter_id);
                    }
                    //章节内容已经存在
                    if (m_file_mgr.CheckChaperExist(t_book_id, t_chapter_id) == true)
                        continue;
                    StartCatchVipChapter(t_book_id, m_ds.Tables[0].Rows[t_index]["bookname"].ToString());

                
                }
            }
        }

        /// <summary>
        /// 开始抓取vip章节
        /// </summary>
        /// <param name="chapterName"></param>
        public void StartCatchVipChapter(long i_book_id,string i_book_name)
        {

            string t_url = "http://tieba.baidu.com/f/good?kw={0}&pn={1}";
            
            string reg_pager_content = "<div[^<>]*?id=[\'\"]?pagebar[\'\"]?>(.*?)</div>";
            string reg_pager_number="<a[^<>]*?hrefs*=s*[\'\"s]?[^\"]*pn=(\\d+)[\'\"s]?.*?>";
            string t_so_url=string.Empty;
            string t_html = string.Empty;


            Match t_pager_mc = null;
            string t_chapter_name=string.Empty;
            int t_max_page_count=0;
            int t_tem_count=0;
      
       
            t_so_url = string.Format(t_url, HttpUtility.UrlEncode(i_book_name,m_encoding), 0);
    
            t_html = BookSiteManager.ReadUrl(t_so_url,m_encoding);

            t_pager_mc = Regex.Match(t_html, reg_pager_content, RegexOptions.IgnoreCase | RegexOptions.Compiled);

            if (t_pager_mc != null && t_pager_mc.Groups.Count > 0)
            {
                MatchCollection t_ma_number=Regex.Matches( t_pager_mc.Groups[1].Value.ToString(),reg_pager_number, RegexOptions.IgnoreCase | RegexOptions.Compiled);
                if(t_ma_number!=null && t_ma_number.Count>0)
                {
                    for(int index=0;index<t_ma_number.Count;index++)
                    {
                        if(!int.TryParse(t_ma_number[index].Groups[1].Value.ToString(),out t_tem_count))
                            t_tem_count=0;
                        if(t_tem_count>t_max_page_count)
                            t_max_page_count=t_tem_count;
                    }
                }
            }

            GetContent(t_html,i_book_id,i_book_name);
       

            if(t_max_page_count>=50)
            {
                int t_total_loop_count=t_max_page_count%50+1;
                for(int index=1;index<t_total_loop_count;index++)
                {
                     t_so_url = string.Format(t_url, HttpUtility.UrlEncode(i_book_name,m_encoding), 50*index);
    
                     t_html = BookSiteManager.ReadUrl(t_so_url,m_encoding);

                    GetContent(t_html,i_book_id,i_book_name);
                }
                
            }
            

           
        }

        private void GetContent(string i_html,long i_book_id,string i_book_name)
        {
            string t_chapter_name=string.Empty;
            string t_reg = "<tr[^<>]*?class.*?tid=[\'\"]?\\d+[\'\"]?>.*?<td[^<>]*?>\\d+</td>.*?<td[^<>]*?>\\d+</td>.*?<td[^<>]*?class.*?>.*?<a[^<>]*?hrefs*=s*[\'\"s]?([^\"]*)[\'\"s]?.*?>(.*?)</a>";
             MatchCollection  t_ma = Regex.Matches(i_html, t_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
             long t_chapter_id=0;
            if (t_ma != null)
            {
                foreach (Match t_mc in t_ma)
                {
                    if (t_mc.Groups.Count > 1)
                    {
                    
                        t_chapter_name = t_mc.Groups[2].Value.ToString();

                        if (IsChpater(t_chapter_name,i_book_name, out t_chapter_id))
                        {
                            StartTieBaCatcha(i_book_id, t_chapter_id, string.Format("http://tieba.baidu.com{0}", t_mc.Groups[1].Value.ToString()));
                          
                        }
                        else
                        {
                            LogHelper.Info(string.Format("bookName={0},url={1},百度贴吧不存在数据", i_book_name, string.Format("http://tieba.baidu.com{0}", t_mc.Groups[1].Value.ToString())));
                        }
                        
                    }
                }   
               
            }
        }

        private bool IsChpater(string i_chapter_name,string i_book_name, out long o_chapter_id)
        {
            
            o_chapter_id = 0;
            string[] t_chapter_name_arr = i_chapter_name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            bool t_result=false;
            if (m_ds == null || m_ds.Tables[0].Rows.Count <= 0)
                return false;
            string t_chapter_name = string.Empty;
            string t_book_name = string.Empty;
            for (int index = 0; index < m_ds.Tables[0].Rows.Count; index++)
            {
                t_chapter_name = m_ds.Tables[0].Rows[index]["chaptername"].ToString();
                t_book_name = m_ds.Tables[0].Rows[index]["bookname"].ToString();
                if (t_chapter_name_arr != null && t_chapter_name_arr.Length > 0)
                {
                    foreach (string t_key in t_chapter_name_arr)
                    {
                        if (t_key.Equals(t_book_name))
                            continue;
                        if (IsContainerChpater(i_chapter_name,t_chapter_name) && i_book_name == t_book_name)
                        {
                            t_result = true;
                            break;
                        }

                    }
                }

                if (t_result)
                {
                    if(!long.TryParse(m_ds.Tables[0].Rows[index]["chapterid"].ToString(),out o_chapter_id))
                        o_chapter_id=0;
                    break;
                }
            }

            return t_result;
        }

        private bool IsContainerChpater(string i_chapter_name, string i_chatch_chapter_name)
        {
            int t_count=4;
            if (i_chapter_name.Length < t_count)
                return false;
            bool t_is_chapter = false;

            for (int index = 0; index < i_chapter_name.Length - t_count; index++)
            {
               if( i_chatch_chapter_name.IndexOf(i_chapter_name.Substring(index, t_count))>-1)
               {
                   t_is_chapter = true;
                   break;
               }

                
               
            }
            return t_is_chapter;
        }

        /// <summary>
        /// 抓取贴吧里的vip章节
        /// </summary>
        /// <param name="i_url"></param>
        /// <returns></returns>
        public bool StartTieBaCatcha(long i_book_id, long i_chapter_id, string i_url)
        {
            string t_html = string.Empty;
            string t_reg = "<td[^<>]*?classs*=s*[\'\"s]?content[\'\"]*?>[^<>]*<p[^<>]*?classs*=s*[\'\"s]?floor[\'\"]*?>\\d{1,}.*?</p>[^<>]*<cc>(.*?)</cc>";
            Encoding t_encoding = Encoding.GetEncoding("gbk");
            t_html = BookSiteManager.ReadUrl(i_url, t_encoding);
            string t_chapter_content = string.Empty;
            MatchCollection t_ma = Regex.Matches(t_html, t_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            int t_index = 0;
            bool t_is_chapter = true;
            StringBuilder t_sb = new StringBuilder();
            if (t_ma != null)
            {
                foreach(Match t_mc in t_ma)
                {
                    if (t_mc.Groups.Count > 0)
                    {
                        t_index++;
                        //最多取5楼
                        if (t_index > 5 || !t_is_chapter)
                            break;
                        t_chapter_content = t_mc.Groups[1].Value.ToString();
                        t_chapter_content = ReplaceContent(t_chapter_content);
                        //一百个字的才算章节内容，否则算回复内容
                        if (t_chapter_content.Length > 200)
                        {
                            t_sb.Append(t_chapter_content);
                        }
                        else
                        {
                            t_is_chapter = false;
                        }
                    }
                }
            }

            t_chapter_content = t_sb.ToString();

            if (!string.IsNullOrEmpty(t_chapter_content))
            {
                t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                m_file_mgr.WriteBookContent(i_book_id, i_chapter_id, t_chapter_content);
                //更新状态
                m_chapter_manager.UpdateChapterContentStatus(i_book_id, i_chapter_id);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 抓取3z中文网的vip章节
        /// </summary>
        /// <param name="i_url"></param>
        /// <returns></returns>
        public bool Start3ZCNCatch(long i_book_id,long i_chapter_id, string i_url)
        {
            string t_html = string.Empty;
            string t_reg = "<td[^<>]*?ids*=s*[\'\"s]?content3zcn[\'\"]*?>(.*?)</td>";
            Encoding t_encoding = Encoding.GetEncoding("gbk");
            t_html = BookSiteManager.ReadUrl(i_url, t_encoding);
            string t_chapter_content=string.Empty;
            Match t_mc = Regex.Match(t_html, t_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            if (t_mc != null)
            {
                if (t_mc.Groups.Count > 0)
                {
                    t_chapter_content=t_mc.Groups[1].Value.ToString();
                    t_chapter_content = ReplaceContent(t_chapter_content);
                }
            }

            if (!string.IsNullOrEmpty(t_chapter_content))
            {
                t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                m_file_mgr.WriteBookContent(i_book_id, i_chapter_id, t_chapter_content);
                //更新状态
                m_chapter_manager.UpdateChapterContentStatus(i_book_id, i_chapter_id);
                return true;
            }

            return false;
        }

        private string ReplaceContent(string i_text)
        {
            if (string.IsNullOrEmpty(i_text))
                return string.Empty;
            i_text = Regex.Replace(i_text, "<a.*?>.*?</a>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<script.*?>.*?</script>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<font.*?>.*?</font>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<div.*?>.*?</div>", "", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return i_text;
        }

        /// <summary>
        /// 百度搜索吧
        /// </summary>
        /// <param name="i_book_id"></param>
        /// <param name="i_chapter_id"></param>
        /// <param name="i_book_name"></param>
        /// <param name="i_chapter_name"></param>
        public void StartCatch(long i_book_id,long i_chapter_id, string i_book_name,string i_chapter_name)
        {
            string t_url = "http://www.baidu.com/s?wd={0}";
            string t_reg_href = "<a[^<>]*?hrefs*=s*[\'\"s]?([^\"]*)[\'\"s]?.*?>";
            string t_reg_content = "<div[^<>]*?id=[\'\"]?text_area[\'\"]?>(.*?)</div>";
            Match t_mc_content = null;
            string t_chapter_content = string.Empty;
            try
            {
                string t_so_url = string.Format(t_url, HttpUtility.UrlEncode(string.Format("{0} {1} 手打", i_book_name, i_chapter_name, m_encoding)));

                string t_html = BookSiteManager.ReadUrl(t_so_url, m_encoding);

                if (!string.IsNullOrEmpty(t_html))
                {
                    MatchCollection t_ma = Regex.Matches(t_html, t_reg_href, RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    if (t_ma != null && t_ma.Count > 0)
                    {
                        foreach (Match t_mc in t_ma)
                        {
                            if (t_mc.Groups[1].Value.ToString().ToLower().IndexOf("shouda8.com") > -1)
                            {
                                t_html = BookSiteManager.ReadUrl(t_mc.Groups[1].Value.ToString(), m_encoding);

                                if (!string.IsNullOrEmpty(t_html))
                                {
                                    t_mc_content = Regex.Match(t_html, t_reg_content, RegexOptions.IgnoreCase | RegexOptions.Compiled);
                                    if (t_mc_content != null && t_mc_content.Groups.Count > 0)
                                    {
                                        t_chapter_content = t_mc_content.Groups[1].Value.ToString();
                                        t_chapter_content = ReplaceContent(t_chapter_content);
                                        if (!string.IsNullOrEmpty(t_chapter_content))
                                        {
                                            t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                                            m_file_mgr.WriteBookContent(i_book_id, i_chapter_id, t_chapter_content);
                                            //更新状态
                                            m_chapter_manager.UpdateChapterContentStatus(i_book_id, i_chapter_id);
                                           
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("抓取章节失败" + ex.ToString());
            }
        }
    }
}
